import WeDisplayShaders from "./WeDisplayShaders";

const WeVolumeBoxVS = `
    in vec3 position3DHigh;
    in vec3 position3DLow;
    in float batchId;
    out vec4 v_positionEC;
    out vec4 vertexPos;
    out vec4 cameraPos;
    void main()
    {
        vec4 p = czm_computePosition();
        v_positionEC = (czm_modelViewRelativeToEye * p);
        vec3 pos = position3DHigh + position3DLow;
        vertexPos = vec4(pos.xyz, 1.0);
        cameraPos = czm_inverseModelView * vec4(0,0,0,1);
        gl_Position = czm_modelViewProjection * vec4(pos.xyz, 1.0);
    }
`;


const WeVolumeBoxFS = `
in vec4 v_positionEC;
in vec4 vertexPos;
in vec4 cameraPos;
void main()
{
    vec4 t0 = vertexPos * u_texgen;
    vec4 te = cameraPos * u_texgen;

    if (te.x>=0.0 && te.x<=1.0 &&
    te.y>=0.0 && te.y<=1.0 &&
    te.z>=0.0 && te.z<=1.0)
    {
    }
    else
    {
        if (te.x<0.0)
        {
            float r = -te.x / (t0.x-te.x);
            te = te + (t0-te)*r;
        }
        if (te.x>1.0)
        {
            float r = (1.0-te.x) / (t0.x-te.x);
            te = te + (t0-te)*r;
        }
        if (te.y<0.0)
        {
            float r = -te.y / (t0.y-te.y);
            te = te + (t0-te)*r;
        }
        if (te.y>1.0)
        {
            float r = (1.0-te.y) / (t0.y-te.y);
            te = te + (t0-te)*r;
        }
        if (te.z<0.0)
        {
            float r = -te.z / (t0.z-te.z);
            te = te + (t0-te)*r;
        }
        if (te.z>1.0)
        {
            float r = (1.0-te.z) / (t0.z-te.z);
            te = te + (t0-te)*r;
        }
    }

    float minValue = Weget_minValue();
    float maxValue = Weget_maxValue();
    float filterMin = Weget_volumeFilterMin();
    float filterMax = Weget_volumeFilterMax();
    float filterGap = Weget_filterGap();

    float topAlpha = Weget_topAlpha();
    float AlphaFuncValue = Weget_alphaFuncValue();
    float num_iterations = clamp(Weget_numIteration(),64.,512.);

    float clipMinX = Weget_clipMinMaxX().x;
    float clipMaxX = Weget_clipMinMaxX().y;
    float clipMinY = Weget_clipMinMaxY().x;
    float clipMaxY = Weget_clipMinMaxY().y;
    float clipMinZ = Weget_clipMinMaxZ().x;
    float clipMaxZ = Weget_clipMinMaxZ().y;

    vec4 worldExtent = Weget_extent();
    bool shouldAnime = Weget_shouldAnime() > 0.0;
    bool shouldFlipY = Weget_shouldFlipY() > 0.0;
    bool isUV = Weget_isUV() > 0.0;

    vec3 texcoord = t0.xyz;

    vec3 deltaTexCoord = (te-t0).xyz/(num_iterations-1.0);
    vec4 fragColor = vec4(0.0, 0.0, 0.0, 0.0);
    while(num_iterations-- > 0.0)
    {
        vec3 st = texcoord;
        vec2 lonLat = WeGetImageryLonLat(st.xy,u_localExtent);
        st.xy = WeGetImageryLocalUV(lonLat,worldExtent);

        if(shouldFlipY){
            st.y = 1.0 - st.y;
        }

        vec4 comp = WeDecodeComponent(st);
        float value = isUV ? length(comp.xy) : comp.x;

        float i = (value - minValue) / (maxValue - minValue);
        vec4 color = texture(u_TFTexture,vec2(i,0.0));
        if(WeIsNodata(value,minValue,filterMin,filterMax)
        || st.x < clipMinX
        || st.y < clipMinY
        || st.z < clipMinZ
        || st.x > clipMaxX
        || st.y > clipMaxY
        || st.z > clipMaxZ){
            color.a = 0.0;
        }

        float i_alpha = i;
        if(filterMin > minValue && filterMin < maxValue)
        {
            i_alpha = (value - filterMin) / (maxValue - filterMin);
        }

        color.a *= i_alpha;
        if(filterGap > 0.0)
        {
          float filterGapFactor = Weget_filterGapFactor();
          float rampV = filterGap;
          float clampV = mod(value,rampV) / rampV;
          float clampP = 1.0 - sin(clampV * czm_piOverTwo);
          color.rgb *=  pow(clampP,1.2);
          clampP = pow(clampP,filterGapFactor);
          color.a *= clampP;
        }


#ifdef ${WeDisplayShaders.WeDefineCalculateNormal3D}
        vec3 normalEC = normalize(comp.yzw);
        vec3 positionToEyeEC = -v_positionEC.xyz;
        czm_material material;
        material.diffuse = color.rgb;
        material.specular = 0.0;
        material.shininess = 0.0;
        material.normal = -normalize(normalEC);
        material.emission = vec3(0.0);
        material.alpha = color.a;
        color = czm_phong(normalize(positionToEyeEC), material, czm_lightDirectionEC);
#endif
        if(topAlpha < st.z){
            color.a *= (1.0 - st.z);
        }

        float r = color.a;
        if (r>AlphaFuncValue)
        {
            fragColor.xyz = fragColor.xyz*(1.0-r)+color.xyz*r;
            fragColor.w += r;
        }
        if (fragColor.w<color.w)
        {
            fragColor = color;
        }
        texcoord += deltaTexCoord;
    }
    if (fragColor.w>1.0) fragColor.w = 1.0;
    if (fragColor.w<AlphaFuncValue) discard;
    out_FragColor = fragColor;
}
`;

export default {
    WeVolumeBoxVS,
    WeVolumeBoxFS,
};
